package com.tierstall.server;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.tierstall.server.model.Gruppe;
import com.tierstall.server.model.Tier;
import com.tierstall.server.model.User;
import com.tierstall.shared.GruppeDTO;
import com.tierstall.shared.Logger;
import com.tierstall.shared.SessionInvalidException;
import com.tierstall.shared.TierDTO;
import com.tierstall.shared.UserDTO;
import com.tierstall.util.HibernateUtil;

@SuppressWarnings("serial")
public class ServiceHelper extends RemoteServiceServlet {

	private static ServiceHelper helper;

	private ServiceHelper() {
	}

	public static ServiceHelper getInstance() {
		if (helper == null)
			helper = new ServiceHelper();
		return helper;
	}

	public boolean checkSession(HttpSession httpSession, String sessionId)
			throws SessionInvalidException {
		// Logger.SERVER_INFO("Client session: " + sessionId +
		// " Server session: "+ getSession().getId() + ".");
		if (httpSession.getId().equals(sessionId)) {
			Logger.SERVER_INFO("Session is up to date");
			return true;
		}
		Logger.SERVER_WARN("Session is deprecated");
		throw new SessionInvalidException();
	}

	public User getUserByUsername(String username) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		List users = null;
		try {
			transaction = session.beginTransaction();
			Query query = session
					.createQuery("from User where USERNAME = :username ");
			query.setParameter("username", username);
			users = query.list();
			// List users = session.createQuery("from User").list();
			User current = null;
			transaction.commit();
		} catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		if (users != null && users.size() == 1) {
			return (User) users.get(0);
		} else {
			Logger.SERVER_WARN("User doesn't exist or exists more than once!");
			return null;
		}
	}

	public UserDTO createUserDTO(User user) {
		return new UserDTO(user.getId().toString(), user.getUsername(),
				user.getPassword(), user.getPermission(), user.getFirstname(),
				user.getLastname(), user.getEmail(), user.getDepartment());
	}

	public TierDTO createTierDTO(Tier tier) {
		UserDTO editor = new UserDTO(tier.getEditor().getId().toString(), tier
				.getEditor().getUsername(), tier.getEditor().getPassword(),
				tier.getEditor().getPermission(), tier.getEditor()
						.getFirstname(), tier.getEditor().getLastname(), tier
						.getEditor().getEmail(), tier.getEditor()
						.getDepartment());
		GruppeDTO group = createGroupDTO(tier.getGroup());
		if (tier.getVater() == null || tier.getMutter() == null) {
			return new TierDTO(tier.getUuid().toString(), group, editor,
					tier.getInternal_number(), tier.getInternal_id(),
					tier.getType(), tier.getEntry(), tier.getDispatch(),
					tier.getOrigin(), tier.getStamm(), tier.getGender(),
					tier.getTypus(), null, null, tier.getNote(),
					tier.getBirthday());
		} else
			return new TierDTO(tier.getUuid().toString(), group, editor,
					tier.getInternal_number(), tier.getInternal_id(),
					tier.getType(), tier.getEntry(), tier.getDispatch(),
					tier.getOrigin(), tier.getStamm(), tier.getGender(),
					tier.getTypus(), createTierDTO(tier.getVater()),
					createTierDTO(tier.getMutter()), tier.getNote(),
					tier.getBirthday());
	}

	public GruppeDTO createGroupDTO(Gruppe group) {
		return new GruppeDTO(group.getUuid().toString(),
				group.getGenehmigung(), group.getLeiter(),
				group.getPermitted_animals(), group.getSpecies(),
				group.getOrigin(), group.getPermitted());
	}
}
